import 'dart:math';

import 'package:ebook/read.dart';
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:ebook/base/Util.dart';
import 'dart:async';
import 'package:ebook/components/Cell.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:html/parser.dart' show parse;
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
// import 'package:html/dom.dart';

class Chapter extends StatefulWidget {
  const Chapter({Key? key, required this.data}) : super(key: key);
  final Map data;

  @override
  _ChapterState createState() => _ChapterState();
}

class _ChapterState extends State<Chapter> {
  List<Map<dynamic, dynamic>> dataList = [];
  EasyRefreshController scroll_controller = EasyRefreshController(
      controlFinishLoad: true, controlFinishRefresh: true);
  @override
  void dispose() {
    scroll_controller.dispose();
    super.dispose();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    Timer(const Duration(milliseconds: 500), () {
      scroll_controller.callRefresh();
      // loadData();
    });
    UtilLog("message:${widget.data}");
  }

  Future loadData() async {
    final String bookUrl = widget.data["url"].toString();
    Util.dio(widget.data["url"].toString(), method: "get").then((value) {
      // final result = value.toResult();
      // UtilLog(value);
      // if (result.item2) {
      //   UtilLog(result);
      //   // setState(() {
      //   //   dataList = List.from(result.item1["result"]);
      //   // });
      // } else {
      //   showAlert(result.item4);
      // }
      final uri = Uri.parse(bookUrl);
      final scheme = uri.scheme;
      final host = uri.host;
      final port = uri.port;
      final prefix = "$scheme://$host/${uri.hasPort ? ":$port" : ""}";
      var document = parse(value.data);
      var i = 0;
      List<Map<String, dynamic>> list = [];
      document.querySelectorAll("a").forEach((element) {
        var name = element.text;
        var link = element.attributes["href"].toString();
        if (name.contains("第") &&
            (name.contains("章") ||
                name.contains("节") ||
                name.contains("部分") ||
                name.contains("回"))) {
          if (!link.startsWith("http")) {
            if (link.startsWith("/")) {
              link = prefix + link;
            } else {
              link = "$prefix/$link";
            }
          }
          list.add({"url": link, "name": name, "id": i, "text": []});
          i++;
        }
        setState(() {
          dataList = list;
        });
        // print(element.outerHtml);
      });
      scroll_controller.finishRefresh(IndicatorResult.success);
    }).catchError((error, stackTrace) {
      UtilLog(error.toString());
      UtilLog(stackTrace);
      scroll_controller.finishRefresh(IndicatorResult.fail);
    });
  }

  Future loadChapter(context, item) async {
    EasyLoading.show(status: "正在加载中……");
    final String bookUrl = item["url"].toString();
    Util.dio(bookUrl, method: "get").then((value) {
      var document = parse(value.data);
      setState(() {
        var text = document.body?.text
                .replaceAll(RegExp(r"^\s*$", multiLine: true), "") ??
            "";
        int lines = ((MediaQuery.of(context).size.height - 10 - 60) /
                oneLineHeight(context, Util.smallBlack,
                    MediaQuery.of(context).size.width - 10))
            .floor();
        var textes = [];
        while (text.isNotEmpty) {
          var t = text.substring(
              0,
              maxCharCountToFit(context, text, Util.smallBlack, lines,
                  MediaQuery.of(context).size.width - 10));
          if (t.isEmpty) {
            text = "";
          } else {
            textes.add(t);
            text = text.substring(t.length);
          }
        }
        item["text"] = textes;
      });
      EasyLoading.dismiss();
    }).catchError((error, stackTrace) {
      UtilLog(error.toString());
      UtilLog(stackTrace);
      EasyLoading.dismiss();
    });
  }

  double oneLineHeight(context, TextStyle style, double maxWidth) {
    final TextPainter textPainter = TextPainter(
      text: TextSpan(
          text:
              "简单的设置appbar高度: Scaffold(appBar:PreferredSize(child:AppBar(),preferredSize:Size.fromHeight(60)); 封装成单独的头部Widget 上文链接: flutter自定简单的设置appbar高度: Scaffold(appBar:PreferredSize(child:AppBar(),preferredSize:Size.fromHeight(60)); 封装成单独的头部Widget 上文链接: flutter自定",
          style: style),
      maxLines: 1,
      textScaleFactor: MediaQuery.of(context).textScaleFactor,
      textDirection: TextDirection.ltr,
    )..layout(maxWidth: maxWidth);
    return textPainter.size.height;
  }

  bool _maxCharCountToFit(context, List<String> splitted, TextStyle style,
      int maxLines, double maxWidth, int position) {
    final TextPainter textPainter = TextPainter(
      text:
          TextSpan(text: splitted.sublist(0, position).join(""), style: style),
      maxLines: maxLines,
      textScaleFactor: MediaQuery.of(context).textScaleFactor,
      textDirection: TextDirection.ltr,
    )..layout(maxWidth: maxWidth);
    return textPainter.didExceedMaxLines;
  }

  int maxCharCountToFit(
      context, String content, TextStyle style, int maxLines, double maxWidth) {
    List<String> splitted = content.split("");
    if (!_maxCharCountToFit(
        context, splitted, style, maxLines, maxWidth, splitted.length - 1)) {
      return splitted.length;
    }
    var min = 0;
    var max = splitted.length;
    var position = max;
    for (var i = 0; i < 32; i++) {
      if (max - min < 5) {
        break;
      }
      position = (((max - min) / 2) + min).floor();
      if (_maxCharCountToFit(
          context, splitted, style, maxLines, maxWidth, position - 1)) {
        max = position;
      } else {
        min = position;
      }
    }
    for (int i = min; i < max; i++) {
      if (_maxCharCountToFit(context, splitted, style, maxLines, maxWidth, i)) {
        return i;
      }
    }
    return 0;
  }

  Future gotoDetail(context, item) async {
    if (item["text"].isNotEmpty) {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (context) => Read(data: item)),
      );
    }
  }

  Future saveChapters() async {
    // Get a location using getDatabasesPath
    var databasesPath = await getDatabasesPath();
    UtilLog(databasesPath);
    String path = join(databasesPath, 'demo.db');

    // Delete the database
    await deleteDatabase(path);
    // open the database
    Database database = await openDatabase(path, version: 1);
    // Insert some records in a transaction
    await database.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT INTO Book(name, url) VALUES("some name", 1234, 456.789)');
      print('inserted1: $id1');
      int id2 = await txn.rawInsert(
          'INSERT INTO Test(name, value, num) VALUES(?, ?, ?)',
          ['another name', 12345678, 3.1416]);
      print('inserted2: $id2');
    });
    database.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text(widget.data["name"].toString()),
          actions: [
            TextButton(
                onPressed: () {
                  saveChapters();
                },
                child: const Text(
                  "保存",
                  style: Util.smallWhite,
                ))
          ],
        ),
        body: EasyRefresh(
          onRefresh: loadData,
          controller: scroll_controller,
          child: ListView(
              children: dataList.isNotEmpty
                  ? dataList
                      .map((e) => TextButton(
                          onPressed: () {
                            gotoDetail(context, e);
                          },
                          child: Cell(
                            title: e["name"].toString(),
                            // islink: true,
                            rightIcon: e["text"].isNotEmpty
                                ? null
                                : TextButton(
                                    onPressed: () {
                                      loadChapter(context, e);
                                    },
                                    child: const Icon(Icons.cloud_download),
                                  ),
                          )))
                      .toList()
                  : [const Text("暫時未有")]),
        ));
  }
}
